2

面向对象编程

面向过程
  • javascript是一门面向过程的语言,也就是侧重点是实现一件事的步骤。
  • 特点:有良好的可扩展性和重用性,降低了代码间的耦合度,接近日常思维。
面向对象
  • 以事物为中心,侧重于完成某件事所需要的事物的特征和行为的设计。
  • 特点:封装、继承、多态,耦合度低,复用度好。

相信这些概念性的东西,网上真的是一搜一大堆,在我使用我的方法理解和上手面向对象之前,容许我把概念性的东西写完,毕竟基础特别重要啊。相信我,如果你正在阅读,请忍耐一两分钟

相关名词
  • prototype : 获取构造函数的原型对象
  • constructor : 获取原型对象的构造函数
  • --proto-- : 获取实例对象的构造函数的原型对象
  • 原型链 : 构造函数自身会有原型对象,通过prototype查看,构造函数的实例对象自身也会有原型对象,通过--proto--查看,--proto--是object类型,当访问一个实例化的属性时,浏览器会先查找自身内部属性,没有就找--proto--,直到--proto--类型为null。
  • New关键字作用:创建一个空对象,让空对象调用构造函数给自己赋值,将该对象返回
继承

实现B继承A

  1. 方式一:在B的构造函数内部写A.call(this);缺点:参数设置不灵活
  2. 方式二:(使用原型链实现继承)step1:改变自身原型对象B.prototype=new A();step2:修复原型对象指向的构造函数B.prototype.constructor=B

好啦,概念性的东西就写到这,下面开始我的代码之旅,现在已经晚上11:30整,我好瞌睡啊,太困了,把这个写完我就去睡觉了Zzzz


基础设置

国际惯例,先把代码的基础设置好

            div,
            p {
                width: 100px;
                height: 30px;
                border: 1px solid #ddd;
                margin: 30px auto;
            }
            div.open,p.open{
                background: pink;
            }


            <body>
                <div></div>
                <div></div>
                <p></p>
                <p></p>
            </body>

1.基础版

        /*NO.1
         * 基础方法
         * 缺点:代码冗余,重复获取元素重复循环操作
         * 功能:修改背景色
         */

        var divs1 = document.getElementsByTagName("div");
        var ps1 = document.getElementsByTagName("p");
        for (var i = 0; i < divs1.length; i++) {
            divs1[i].style.backgroundColor = "pink";
        }
        for (var i = 0; i < ps1.length; i++) {
            ps1[i].style.backgroundColor = "pink";
        }

2.进阶版(一)

        /*NO.2
         * 进阶方法
         * 缺点:太局限,只能设置样式
         * 功能:修改背景色
         */
        function getDOM(tagName){
            return document.getElementsByTagName(tagName);
        }
        function setStyle(arr,styleName,styleVal){
            for (var i = 0; i < arr.length; i++) {
                arr[i].style[styleName] = styleVal;
            }
        }
        var divs2 = getDOM("div");
        var ps2 = getDOM("p");
        setStyle(divs2,"backgroundColor","#00a09d");
        setStyle(ps2,"backgroundColor","#00a09d");

3.进阶版(二)

        /*NO.3
         * 进阶方法
         * 缺点:代码不利于阅读,没有结构化
         * 功能:修改宽度,填充文字,遍历封装
         */
        function getDOM(tagName){
            return document.getElementsByTagName(tagName);
        }
        function each(arr,callback){
            for (var i = 0; i < arr.length; i++) {
                callback(arr[i])
            }
        }
        var divs2 = getDOM("div");
        var ps2 = getDOM("p");
        each(divs2,function(tag){    
            tag.style.width = "200px";
            tag.innerText = "I have a pen!!!";
        })

4.进阶版(三)

        /*NO.4
         * 进阶方法,传统面向对象写法(独立作用域)
         * 功能:添加样式,遍历封装
         */
        function Tool(bgColor){
            this.bgColor = bgColor||"#00a09d";
            this.getDom = function(tagName){
                return document.getElementsByTagName(tagName);
            };
            this.each = function(arr,callback){
                for (var i = 0; i < arr.length; i++) {
                    arr[i].style.backgroundColor = this.bgColor;
                    callback(arr[i]);
                }
            };
        }
        //实例化(使用)
        var tool = new Tool();
        var ps3 = tool.getDom("p");
        var divs3 = tool.getDom("div");
        tool.each(divs3,function(tag){    
            tag.style.width = "200px";
            tag.innerText = "I have a pen!!!";
        })

5.终极版

        /*NO.5
         * 进阶方法,ES6面向对象写法(独立作用域,类本身指向构造函数)
         * 功能:将传入的对象变成红色,填充文字,添加点击效果(歪楼了,需求改成这怂样子了)
         * 说明:实例化之后立即实现以上功能
         * 功能:修改背景,填充文字,绑定事件......
         */
        class Tool{
            //构造函数(options为实例化传入的参数)
            //作用:设置默认参数,合并默认参数和传入的参数,实现继承
            constructor(options){
                let dafultOpations = {
                    element:"",
                    bgColor:"red",
                    color:"#fff"
                }
                
                this.options = Object.assign({},dafultOpations,options); //合并对象   assign(相同项会覆盖) merge(相同项会合并)
                this.checkOptions().setStyle().setText().bindClick()  //实例化后立即执行这些方法,每个方法在调用完成后一定要释放this
            }
            //由于该类的实现依赖于传入的DOM,此方法用来确保已经传入DOM,若实例化没有传入,则抛出异常
            checkOptions(){
                if(!this.options.element){
                    throw new Error("Element is required!!!")
                }
                return this;
            }
            setStyle(){
                for (var i = 0; i < this.options.element.length; i++) {
                    this.options.element[i].style.backgroundColor = this.options.bgColor;
                    this.options.element[i].style.textAlign = "center";
                    this.options.element[i].style.color = this.options.color;
                }
                return this;
            }
            setText(){
                for (var i = 0; i < this.options.element.length; i++) {
                    this.options.element[i].innerText = "呆呆Akuma";
                }
                return this;
            }
            bindClick(){
                for (var i = 0; i < this.options.element.length; i++) {
                    let __this = this.options.element[i];  //需将当前的元素区分开 __this!=this
                    let flag = false;
                    __this.addEventListener("click",()=>{
                        if(flag = !flag){                            
                            __this.style.backgroundColor = "pink"
                        }else{
                            __this.style.backgroundColor =     this.options.bgColor;                    
                        }
                    })
                }
                return this;
            }
        }
        
        
        
        var divs = new Tool({
            element:document.getElementsByTagName("div"),
            bgColor:"#00a09d"
        });
        var ps = new Tool({
            element:document.getElementsByTagName("p"),
            bgColor:"#f48"
        });

目前看起来,这个终极版好像是最繁琐的,首先我要说明,这里只是介绍面向对象编程是怎么回事,对于漫天飞的this真的神烦,不过多写写就好了,习惯就好,要学会控制它,如果你成功看完这篇文章,你就会发现,随着版本(暂时就算版本吧)升级,功能也慢慢增多,灵活性更好,代码的可扩展性更高啦,至于质疑一个简单的功能至于写这么复杂吗?

很好,我觉得面向对象编程就是造轮子的过程,轮子就相当于工具。打个比方,伐树你会选择电锯还是斧头,劈柴你会选择电锯还是斧头,相信答案就在你心里,好了不写了,真困了,快睡着了。


miomiomio
147 声望5 粉丝

人生昧履,砥砺而行